package com.stb.shared.util;

import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.TreeSet;

public final class SetFactory 
{
	private SetFactory() {
	}
	
	/**
	 * Create a "read-only" set from specified values 
	 * @param values
	 * @return unmodifiable set from specified values
	 */
	public static <T> Set<T> create(T... values) {
		return create(Arrays.asList(values));
	}

	public static <T> Set<T> createSorted(T... values) {
		return createSorted(null, Arrays.asList(values));
	}
	
	public static <T> Set<T> createSortedWithComparator(Comparator<T> comparator, T... values) {
		return createSorted(comparator, Arrays.asList(values));
	}
	
	/**
	 * Create a "read-only" linked set from specified values 
	 * @param values
	 * @return unmodifiable linked set from specified values
	 */
	public static <T> Set<T> createLinked(T... values) {
		return createLinked(Arrays.asList(values));
	}

	/**
	 * Create a "read-only" set from specified values 
	 * @param values
	 * @return unmodifiable set from specified values
	 */
	public static <T> Set<T> create(Collection<T> values) {
		return create(new HashSet<T>(values.size()), values);
	}

	public static <T> Set<T> createSorted(Comparator<T> comparator, Collection<T> values) {
		return create(new TreeSet<T>(comparator), values);
	}

	private static <T> Set<T> create(Set<T> set, Collection<T> values) {
		set.addAll(values);
		return Collections.unmodifiableSet(set);
	}

	/**
	 * Create a "read-only" linked set from specified values 
	 * @param values
	 * @return unmodifiable linked set from specified values
	 */
	public static <T> Set<T> createLinked(Collection<T> values) {
		return create(new LinkedHashSet<T>(values.size()), values);
	}

	public static <T> Set<T> union(Set<T> first, Set<T> second) {
		Set<T> result = new HashSet<T>(first.size() + second.size());
		result.addAll(first);
		result.addAll(second);
		return Collections.unmodifiableSet(result);
	}
}
